#include <cstdio>
//#include "AbstractCell.h"
#include <vector>

using namespace std;

class FredkinCell : public AbstractCell {
	
	private:
	/**
	* @param gen number of generations the cell has been continueously alive. -1 if cell is dead
 	*/
	int gen;

	public:
	
	/**
 	* Default constructor. Cell is dead by default
 	*/
	FredkinCell():
	gen(-1)
	{}

	/**
 	* constructor
 	* @param a age of the cell
 	*/
	FredkinCell(int a):
	gen(a)
	{}
	
	/**
 	* returns whether the cell is alive or not
	* @return true if alive, false is dead
 	*/
	bool isAlive(){
		return gen>-1;
	}
	
	/**
 	* evolves the cell at (x,y) given the alive neighbor count in neighbors
 	* @param neighbors alive neighbor count. neighbors[1] is FredkinCell neighbors
	* @param x x coordinate of cell
	* @param y y coordinate of cell
	* @return true if extra processing is needed in Cell.h. false otherwise
 	*/
	bool evolve(vector<vector<vector<int> > >& neighbors, int x, int y){
		int n=neighbors[1][x][y];
		if(isAlive()){
			if(n==0||n==2||n==4){
				gen=-1;
			}
			else{
				++gen;
				return true;
			}	
		}
		else{
			if(n==1||n==3){
				gen=0;
			}
		}
		return false;
	}
	
	/**
 	* increments live neighbor count around cell (X,Y). Cell must be alive for this to make sense.
 	* @param neighbors alive neighbor count. neighbors[1] is FredkinCell neighbors
	* @param X x coordinate of cell
	* @param Y y coordinate of cell
 	*/
	void updateNeighborCount(vector<vector<vector<int> > >& neighbors, int X, int Y){
		vector<vector<int> >* n = &neighbors[1];
		++((*n)[X+1][Y]);
		++((*n)[X][Y+1]);
		++((*n)[X-1][Y]);
		++((*n)[X][Y-1]);
		
	}
	
	/**
 	* prints the cell
 	*/
	void print(){
		if(isAlive()){
			if(gen>9)
				printf("+");
			else
				printf("%d",gen);
		}
		else
			printf("-");
	}
	
	/**
 	* set the state of the cell
	* @param c char that represents the cell's state
 	*/
	void setCell(char c){
		if(c=='-')
			gen=-1;
		else
			gen=0;
	}
	
	/**
 	* resets the live neighbor counts for the FredkinCell neighbor grid
 	* @param neighbors alive neighbor count. neighbors[1] is FredkinCell neighbors
 	*/
	static void resetNeighborCount(vector<vector<vector<int> > >& neighbors){
		for(int x=0;x<neighbors[1].size();++x){
			for(int y=0; y<neighbors[1][0].size(); ++y){
				neighbors[1][x][y]=0;	
			}
		}
	}
	
	/**
 	* Returns how long the cell has been alive.
 	* @return global variable "gen"
 	*/
	int getAge(){
	return gen;
	}

	/**
 	* Returns an integer representation of the cell type.
 	* @return 1
 	*/
	int getType(){
		return 1;
	}	

};
